// Copyright (c) 2021 by Rockchip Electronics Co., Ltd. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/*-------------------------------------------
                Includes
-------------------------------------------*/

#include <float.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <vector>

#include "taiic_vsr.h"

/*-------------------------------------------
                  Functions
-------------------------------------------*/
static inline int64_t getCurrentTimeUs()
{
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return tv.tv_sec * 1000000 + tv.tv_usec;
}

/*-------------------------------------------
                  Main Functions
-------------------------------------------*/
int main(int argc, char *argv[])
{
    if (argc < 3)
    {
        printf("Usage:%s model_path input_path [loop_count]\n", argv[0]);
        return -1;
    }

    char *input_path = argv[2];

    int loop_count = 1;
    if (argc > 3)
    {
        loop_count = atoi(argv[3]);
    }
    VSR_TOOLKIT_MODEL_CTX_S *vsr_ctx;                                                               // 模型推理相关
                                                                                                    //  模型推理相关
    vsr_ctx = reinterpret_cast<VSR_TOOLKIT_MODEL_CTX_S *>(malloc(sizeof(VSR_TOOLKIT_MODEL_CTX_S))); // 分配内存空间
    memset(vsr_ctx, 0, sizeof(VSR_TOOLKIT_MODEL_CTX_S));

    vsr_ctx->modelPath = argv[1];
    vsr_rknn_toolkit_config_init(vsr_ctx);
    vsr_rknn_toolkit_io_init(vsr_ctx);

    unsigned char *input_data = NULL;
    // load test file
    input_data = new unsigned char[vsr_ctx->input_attrs[0].size];

    FILE *fp = fopen(input_path, "rb");
    printf("==load fiel is %s==\n", input_path);
    if (fp == NULL)
    {
        perror("open failed!");
        return -1;
    }
    fread(input_data, vsr_ctx->input_attrs[0].size, 1, fp); // 读取输入数据
    fclose(fp);

    if (!input_data)
    {
        return -1;
    }

    vsr_rknn_toolkit_data_refresh(vsr_ctx, input_data);
    printf("=====s=\n");

    // Run
    printf("Begin perf ...\n");
    for (int i = 0; i < loop_count; ++i)
    {
        int64_t start_us = getCurrentTimeUs();
        // printf("===start run===\n");
        int ret = rknn_run(vsr_ctx->context, NULL);

        // printf("====end run===\n");
        int64_t elapse_us = getCurrentTimeUs() - start_us;
        if (ret < 0)
        {
            printf("rknn run error %d\n", ret);
            return -1;
        }
        printf("%4d: Elapse Time = %.2fms, FPS = %.2f\n", i, elapse_us / 1000.f, 1000.f * 1000.f / elapse_us);
    }

    MODEL_RESULT_S result = vsr_rknn_toolkit_result_int8(vsr_ctx);
    printf("==result is %d, prob is %f==\n", result.label, result.prob);

  
    // Destroy rknn memory
    rknn_destroy_mem(vsr_ctx->context, vsr_ctx->input_mems[0]);
    for (uint32_t i = 0; i < vsr_ctx->io_num.n_output; ++i)
    {
        rknn_destroy_mem(vsr_ctx->context, vsr_ctx->output_mems[i]);
        // free(output_mems_nchw[i]);
    }

    // destroy
    rknn_destroy(vsr_ctx->context);
    free(input_data);

    return 0;
}
